using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Linq.Mapping;
using System.Runtime.Serialization;
using System.Transactions;
using Portal.Data.Helper;
using Portal.Data.Webparts;
using Portal.Core.Binding.FormBuilder;
using Portal.Core.Helper;
using System.Linq;
using Portal.Core.Utils;

namespace Portal.Data.Entity
{
    [Table(Name = "dbo.Webpart"), Serializable, DataContractAttribute]
    public class Webpart : BaseObject
    {
        #region Properties
        public int ID { get { return Webpart_ID; } set { Webpart_ID = value; } }

        [SkipBinding]
        [ColumnAttribute(Name = "Webpart_ID", IsPrimaryKey = true, IsDbGenerated = true)]
        public int Webpart_ID { get; set; }

        [ColumnAttribute(Name = "Page_ID")]
        public int Page_ID { get; set; }

        [ColumnAttribute(Name = "WebPartOrder")]
        public int WebPartOrder { get; set; }

        [ColumnAttribute(Name = "Properties")]
        public string Properties { get; set; }

        [ColumnAttribute(Name = "Definition_ID")]
        public int Definition_ID { get; set; }

        [ColumnAttribute(Name = "Zone")]
        public string Zone { get; set; }


        #endregion

        #region Extension Props
        public string DisplayName()
        {
            var def = Definition();
            var name = "[" + Zone + "] " + ((def != null) ? def.Name : "Widget NULL");
            var cf = GetConfig();
            if (cf != null && !string.IsNullOrEmpty(cf.Title))
                name += " - " + cf.Title;
            return name;
        }
        public WebpartDefinition Definition()
        {
            return WebpartDefinition.FindByPrimaryKey(Definition_ID);
        }
        public WebpartConfig GetConfig()
        {
            //getcache  -----------------------
            var parameter = new object[] { typeof(Webpart).Name, "GetConfig", ID };
            var obj = CacheHelper.Instance.Get(parameter);
            if (obj != null)
                return (WebpartConfig)obj;

            var result = (WebpartConfig)SerializationHelper.Deserialize(Properties);
            CacheHelper.Instance.Set(parameter, result);
            return result;
        }
        public void SetConfig(WebpartConfig newConfig)
        {
            Properties = SerializationHelper.Serialize(newConfig);
            var parameter = new object[] { typeof(Webpart).Name, "GetConfig", ID };
            CacheHelper.Instance.Set(parameter, newConfig);
        }

        #endregion


        #region Methods
        public static Webpart FindByPrimaryKey(object objectid)
        {
            return FindByPrimaryKey<Webpart>(objectid);
        }
        public static Webpart FindByPrimaryKeyRecache(object objectid)
        {
            return FindByPrimaryKey<Webpart>(objectid, true);
        }

        public static List<Webpart> FindByWebpartPage(int wppId, bool renewCaching = false)
        {
            //getcache  -----------------------
            var parameter = new object[] { typeof(Webpart).Name, "FindByWebpartPage", wppId };
            if (!renewCaching)
            {
                var obj = CacheHelper.Instance.Get(parameter);
                if (obj != null)
                    return (List<Webpart>)obj;
            }
            //end get cache -------------------

            using (var context = new CmsDataContext())
            {
                context.Connection.Open();
                var results = context.Webparts.Where(o => o.Page_ID == wppId).OrderBy(o => o.Zone).ThenBy(o => o.WebPartOrder).ToList();
                CacheHelper.Instance.Set(parameter, results);
                return results;
            }
        }
        public static List<Webpart> ListByZonePageDef(string zone, int wppId, int webpartDefinitionId, bool renewCaching = false)
        {
            if (string.IsNullOrEmpty(zone)) return new List<Webpart>();
            zone = zone.ToLower();

            var parameter = new object[] { typeof(Webpart).Name, "ListByZonePageDef", wppId, webpartDefinitionId };
            if (!renewCaching)
            {
                var obj = CacheHelper.Instance.Get(parameter);
                if (obj != null)
                {
                    var results = (List<Webpart>)obj;
                    return results.Where(x => x.Zone != null && x.Zone.ToLower() == zone).ToList();
                }
            }

            using (var context = new CmsDataContext())
            {
                context.Connection.Open();
                var results = context.Webparts.Where(o => o.Page_ID == wppId && o.Definition_ID == webpartDefinitionId).OrderBy(o => o.WebPartOrder).ToList();
                CacheHelper.Instance.Set(parameter, results);
                return results.Where(x => x.Zone != null && x.Zone.ToLower() == zone).ToList();
            }
        }
        public static IList ListAll()
        {
            //getcache  -----------------------
            var parameter = new object[] { typeof(Webpart).Name, "ListAll" };
            var obj = CacheHelper.Instance.Get(parameter);
            if (obj != null)
                return (IList)obj;
            //end get cache -------------------

            var value = LINQHelper.GetList<Webpart>("select * from Webpart order by WebPartOrder");

            CacheHelper.Instance.Set(parameter, value);
            return value;
        }
        public static int GetNextOrder(int wppId)
        {
            const string sql = "select MAX(WebPartOrder) from Webpart where Page_ID={0}";
            try
            {
                return LINQHelper.GetFirst<int>(sql, wppId) + 1;
            }
            catch { }
            return 1;
        }
        public static int RemoveFromWebpartPage(int wppId)
        {
            const string sql = "delete Webpart where Page_ID={0}";
            return LINQHelper.ExecuteNonQuery(sql, wppId);
        }
        public override void AfterSaveUpdate()
        {
            base.AfterSaveUpdate();
            Recache();
        }
        public override void Delete()
        {
            base.Delete();
            Recache();
        }
        public void Recache()
        {
            FindByPrimaryKeyRecache(ID);
            FindByWebpartPage(Page_ID, true);
            WebpartDefinition.FindByPrimaryKeyRecache(Definition_ID);
            var parameter = new object[] { typeof(Webpart).Name, "ListAll" };
            CacheHelper.Instance.Set(parameter, null);
        }
        #endregion Methods
    }
}
